<?php

namespace app\modules\Admin\service;

use \Cache;

class Redis extends Cache
{
    /**
     * @return bool|string|\Redis
     */
    public static function connection(): bool|string|\Redis
    {
        try {
            return parent::connection();
        } catch (\Exception $e) {
            return $e->getMessage();
        }
    }

    /**将哈希表 key 中的字段 field 的值设为 value 。
     * @param string $key
     * @param string $field
     * @param string $value
     * @return bool|int
     * @throws \Exception
     */
    public static function hset(string $key, string $field, string $value): bool|int
    {
        $key = CACHE_KEY_PREFIX . $key;

        return self::connection()->HSET($key, $field, $value);
    }

    /** 只有在字段 field 不存在时，设置哈希表字段的值。
     * @param string $key
     * @param string $field
     * @param string $value
     * @return bool
     * @throws \Exception
     */
    public static function hsetnx(string $key, string $field, string $value): bool
    {
        $key = CACHE_KEY_PREFIX . $key;
        return self::connection()->HSETNX($key, $field, $value);
    }

    /**同时将多个 field-value (域-值)对设置到哈希表 key 中。
     * @param $key
     * @param array $field_array  [field1 => $value1, field2 => $value2]
     * @return bool
     * @throws \Exception
     */
    public static function hmset($key, array $field_array): bool
    {
        $key = CACHE_KEY_PREFIX . $key;
        return self::connection()->HMSET($key, $field_array);
    }

    /**获取所有哈希表中的字段(field)
     * @param string $key
     * @return array [field1,field2]
     * @throws \Exception
     */
    public static function hkeys(string $key): array
    {
        $key = CACHE_KEY_PREFIX . $key;
        return self::connection()->HKEYS($key);
    }

    /**获取哈希表中所有值(value)
     * @param string $key
     * @return array [value1,value2]
     * @throws \Exception
     */
    public static function hvals(string $key): array
    {
        $key = CACHE_KEY_PREFIX . $key;
        return self::connection()->HVALS($key);
    }

    /**获取所有给定字段的值([value1,value2])
     * @param string $key
     * @param array $field_array [field1, field2]
     * @return array [value1,value2]
     * @throws \Exception
     */
    public static function hmget(string $key, array $field_array): array
    {
        $key = CACHE_KEY_PREFIX . $key;
        return self::connection()->HMGET($key, $field_array);
    }

    /**获取哈希表中字段的数量
     * @param string $key
     * @return false|int
     * @throws \Exception
     */
    public static function hlen(string $key): bool|int
    {
        $key = CACHE_KEY_PREFIX . $key;
        return self::connection()->HLEN($key);
    }

    /**获取哈希表中字段值的长度
     * @param string $key
     * @param string $field
     * @return int
     * @throws \Exception
     */
    public static function hstrlen(string $key, string $field): int
    {
        $key = CACHE_KEY_PREFIX . $key;
        return self::connection()->HSTRLEN($key, $field);
    }

    /**获取在哈希表中指定 key 的所有字段和值
     * @param string $key
     * @return array [field1 => $value1, field2 => $value2]
     * @throws \Exception
     */
    public static function hgetall(string $key): array
    {
        $key = CACHE_KEY_PREFIX . $key;
        return self::connection()->HGETALL($key);
    }

    /**获取存储在哈希表中指定字段的值
     * @param string $key
     * @param string $field
     * @return false|string
     * @throws \Exception
     */
    public static function hget(string $key, string $field): bool|string
    {
        $key = CACHE_KEY_PREFIX . $key;
        return self::connection()->HGET($key, $field);
    }

    /**查看哈希表 key 中，指定的字段是否存在。
     * @param string $key
     * @param string $field
     * @return bool
     * @throws \Exception
     */
    public static function hexists(string $key, string $field): bool
    {
        $key = CACHE_KEY_PREFIX . $key;
        return self::connection()->HEXISTS($key, $field);
    }

    /**删除一个或多个哈希表字段
     * @param string $key
     * @param array $field_array [field1, field2, ...otherFields]
     * @return bool|int
     * @throws \Exception
     */
    public static function hdel(string $key, array $field_array): bool | int
    {
        $key = CACHE_KEY_PREFIX . $key;
        $field_str = implode(',', $field_array);
        return self::connection()->HDEL($key, $field_str);
    }

    /**迭代哈希表中的键值对
     * @param string $key
     * @param int $cursor 游标
     * @param string|null $pattern 匹配的模式
     * @param int $count 默认值为 10
     * @return array
     * @throws \Exception
     */
    public static function hscan(string $key, int $cursor, string $pattern = null, int $count = 10)
    {
        $key = CACHE_KEY_PREFIX . $key;
        return self::connection()->HSCAN($key, $cursor, $pattern, $count);
    }

    /**
     * @return bool
     */
    public static function ping(): bool
    {
        try {
            self::connection()->ping();
            return true;
        } catch (\RedisException | \Exception $e) {
            return false;
        }
    }

    /**
     * @param array|string $key_array
     * @return int
     * @throws \Exception
     */
    public static function del(array|string $key_array): int
    {
        if(is_string($key_array)){
            $key_array = [$key_array];
        }
        foreach ($key_array as &$key){
            $key = CACHE_KEY_PREFIX . $key;
        }
        return self::connection()->DEL($key_array);
    }

    /**
     * @param array|string $key_array
     * @return int
     * @throws \Exception
     */
    public static function delHasPrefix(array|string $key_array): int
    {
        if(is_string($key_array)){
            $key_array = [$key_array];
        }
        return self::connection()->DEL($key_array);
    }

    /**
     * @param string $pattern
     * @return array
     */
    public static function keys(string $pattern): array
    {
        if(empty($pattern)){
            $pattern = '*';
        }else{
            $pattern = '*'. $pattern.'*';
        }
        return self::connection()->KEYS($pattern);
    }
}